using System;
using System.Threading;

namespace Dida
{
	public class ThreadBridge
	{
		int inBuffer = 0;
		int outBuffer = 1;
		int pendingOut = 1;
		Mutex backbuffersMutex = new Mutex();

		public void SwapIn()
		{
			backbuffersMutex.WaitOne();

			pendingOut = inBuffer;
			
			inBuffer = (inBuffer + 1) % 3;
			if (inBuffer == outBuffer)
				inBuffer = (inBuffer + 1) % 3;

			backbuffersMutex.ReleaseMutex();
		}

		public void SwapOut()
		{
			backbuffersMutex.WaitOne();

			outBuffer = pendingOut;

			backbuffersMutex.ReleaseMutex();
		}

		public int InBuffer
		{
			get { return inBuffer; }
		}

		public int OutBuffer
		{
			get { return outBuffer; }
		}
	}

	public class ThreadBridgedValue<T>
	{
		T[] backbuffers = new T[3];
		ThreadBridge bridgeType;

		private ThreadBridgeOut<T> outAniValue;

		public ThreadBridgedValue(ThreadBridge bridgeType)
		{
			this.bridgeType = bridgeType;

			outAniValue = new ThreadBridgeOut<T>(this);
		}

		public IAniValue<T> Out
		{
			get
			{
				return outAniValue;
			}
		}

		internal T OutValue
		{
			get
			{
				return backbuffers[bridgeType.OutBuffer];
			}
		}
	}

	internal class ThreadBridgeOut<T> : IAniValue<T>
	{
		ThreadBridgedValue<T> threadBridge;

		public ThreadBridgeOut(ThreadBridgedValue<T> threadBridge)
		{
			this.threadBridge = threadBridge;
		}

		public T CurrentValue
		{
			get 
			{
				return threadBridge.OutValue;
			}
		}

		public void Start()
		{
			// nothing todo..
		}

		public void Update(float timeDelta)
		{
			// nothing todo...
		}
	}
}	